package xyz.xtt.pay.mq;

import static xyz.xtt.common.asset.AssertUtils.isNull;

import java.nio.charset.StandardCharsets;
import java.time.ZoneId;
import java.util.Objects;

import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

import com.google.common.primitives.Longs;

import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import xyz.xtt.asset.client.request.CancelTransactionRequest;
import xyz.xtt.asset.client.response.TransactionResponse;
import xyz.xtt.pay.api.dto.BusinessOrderStatusChangeMsg;
import xyz.xtt.pay.constants.ErrorMessage;
import xyz.xtt.pay.entity.TblBusinessOrder;
import xyz.xtt.pay.service.IInnerService;
import xyz.xtt.pay.service.ITblBusinessOrderService;
import xyz.xtt.pay.service.ITblPayLimitService;

/**
 * @author dale
 * @date 2025/3/19
 **/
@RefreshScope
@Slf4j
@Component
@RocketMQMessageListener(topic = "${rocketmq.business.order.status.change.topic:nft_pay_business_order_status_change_topic}", selectorExpression = "normal_pay_cancel||rose_mint_pay_cancel||c_to_c_pay_cancel||buy_asset_1155_pay_cancel", consumerGroup = "${rocketmq.consumer.group.asset.nft.purchase.pay.cancel:nft_asset_nft_purchase_pay_cancel_group}")
public class NftPurchaseBusinessOrderPayCancelConsumer implements RocketMQListener<MessageExt> {
	@Autowired
	private ITblBusinessOrderService iTblBusinessOrderService;
	@Autowired
	private ITblPayLimitService iTblPayLimitService;
	@Autowired
	private IInnerService iInnerService;

	@Override
	public void onMessage(MessageExt msg) {
		String msgId = msg.getMsgId();
		String tags = msg.getTags();
		byte[] body = msg.getBody();
		String message = new String(body, StandardCharsets.UTF_8);
		log.info("NftPurchaseBusinessOrderPayCancelConsumer msgId:{} tags:{} message: {}", msgId, tags, message);
		if (StringUtils.isEmpty(message)) {
			return;
		}
		if (!JSONUtil.isTypeJSON(message)) {
			log.warn("NftPurchaseBusinessOrderPayCancelConsumer Received message: {} is not json", message);
			return;
		}

		BusinessOrderStatusChangeMsg statusChangeMsg = JSONUtil.toBean(message, BusinessOrderStatusChangeMsg.class);
		isNull(statusChangeMsg, ErrorMessage.ARGUMENT_NOT_VALID);
		log.info("NftPurchaseBusinessOrderPayCancelConsumer statusChangeMsg: {} tag:{}", message, tags);
		TblBusinessOrder businessOrder = iTblBusinessOrderService.getById(statusChangeMsg.getBusinessOrderId());
		if (businessOrder == null) {
			log.error("NftPurchaseBusinessOrderPayCancelConsumer can not find businessOrder by id:{}", statusChangeMsg.getBusinessOrderId());
			return;
		}
		TransactionResponse transaction = iInnerService.transactionInfo(Longs.tryParse(businessOrder.getBusinessRefId()));
		if (Objects.isNull(transaction)) {
			log.info("transaction is null msg:{}", message);
			return;
		}
		CancelTransactionRequest cancelTransactionRequest = CancelTransactionRequest
				.builder()
				.orderId(transaction.getOrderId())
				.from(Long.valueOf(transaction.getSellerUserId()))
				.to(Long.valueOf(transaction.getBuyerUserId()))
				.assetId(transaction.getAssetId())
				.build();
		iInnerService.cancelTransaction(cancelTransactionRequest);

		if (Objects.equals(tags, "C_TO_C:PAY_CANCEL")) {
			// 需要恢复已预占的支付额度限制
			iTblPayLimitService
					.cancelUserPayLimit(businessOrder.getAppUserId(), Long.valueOf(businessOrder.getSellerId()), businessOrder
							.getTotalPrice(), businessOrder.getCreateTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
		}
	}
}
